#![allow(dead_code)]
use anyhow::Result;
use reqwest::header::{HeaderMap, CONTENT_TYPE};
use reqwest::{multipart, ClientBuilder};
use std::collections::HashMap;
use std::fs::File;
use std::io::{BufWriter, Write};
use serde::Deserialize;

#[tokio::main]
async fn main() -> Result<()> {
    download_file().await
}

/// 客户端
async fn client() -> Result<()> {
    let mut headers = HeaderMap::new();
    headers.insert(CONTENT_TYPE, "application/json".parse()?);

    let _client = reqwest::Client::builder()
        // 为客户端启用持久性 Cookie 存储。
        .cookie_store(true)
        // 设置默认的请求头
        .default_headers(headers)
        .build()?;
    Ok(())
}

/// 阻塞客户端
fn blocking() -> Result<()> {
    let client = reqwest::blocking::Client::builder().build()?;
    let _response = client.get("/blocking").send()?;
    Ok(())
}

#[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")]
struct User{
    name: String,
    is_male: Option<bool>
}

/// get请求
async fn get() -> Result<()> {
    let body = reqwest::get("http://localhost:8080/get?name=sjt")
        .await?;
    let headers = body.headers();
    for (key, value) in headers {
        println!("{}: {:?}", key, value);
    }
    let content_type = headers.get(CONTENT_TYPE);
    
    match content_type { 
        Some(content_type) if content_type == "application/json" => {
            let json: User = body
                .json()
                .await?;
            println!("json = {json:?}");
        },
        
        _ => {
            let text = body
                .text()
                .await?;
            println!("text = {text:?}");
        }
    }
    Ok(())
}

/// post请求
async fn post() -> Result<()> {
    let client = reqwest::Client::new();
    let res = client.post("http://httpbin.org/post")
        .body("the exact body that is sent")
        .send()
        .await?;

    let body = res.text().await?;
    println!("{}", body);
    Ok(())
}

/// 表单请求
async fn post_form() -> Result<()> {
    let client = reqwest::Client::new();
    // 参数可以是HashMap 也可以是两个元素类型的数组或列表
    let mut params = HashMap::new();
    // let params = [("baz", "quux"), ("foo", "quux")];
    params.insert("baz", "quux");
    let res = client.post("http://httpbin.org/post")
        .form(&params)
        .send()
        .await?;

    let body = res.text().await?;
    println!("{}", body);
    Ok(())
}

/// json 请求
async fn post_json() -> Result<()> {
    let client = reqwest::Client::new();
    let mut map = HashMap::new();
    map.insert("name", "sjt");
    let res = client.post("http://localhost:8080/post")
        .json(&map)
        .send()
        .await?;

    let body = res.text().await?;
    println!("{}", body);
    Ok(())
}

/// 文件上传 需开启feature：["multipart", "stream"]  
async fn post_file() -> Result<()> {
    let client = reqwest::Client::new();
    let form = multipart::Form::new()
        .text("name", "sjt")
        .text("isMale", "true")
        .file("file", "rsa_pri.pem")
        .await?;
    let res = client.post("http://localhost:8080/file")
        .multipart(form)
        .send()
        .await?;

    let body = res.text().await?;
    println!("{}", body);
    Ok(())
}
/// cookies存储 需开启feature：["cookies"]  
async fn get_cookie() -> Result<()> {
    let client = ClientBuilder::new()
        .cookie_store(true)
        .build()?;
    let res = client.post("http://localhost:8080/cookie1")
        .send()
        .await?;
    let cookies = res.cookies();
    for cookie in cookies {
        println!("{}-{}", cookie.name(), cookie.value())
    }
    let body = res.text().await?;
    println!("{}", body);
    let res = client.post("http://localhost:8080/cookie2")
        .send()
        .await?;
    let body = res.text().await?;
    println!("{}", body);
    Ok(())
}

/// 文件下载
async fn download_file() -> Result<()> {
    let client = reqwest::Client::new();
    let mut map = HeaderMap::new();
    map.insert("content-type", "application/json".parse()?);
    map.insert("token", "58cd224363b846f191809eb8a3b4fc3c1763707662176".parse()?);
    map.insert("system", "sys".parse()?);

    let mut params = HashMap::with_capacity(2);
    params.insert("startDate", "2025-11");
    let mut res = client.post("http://106.120.42.106:16280/api/restaurant/settlement/export")
        .headers(map)
        .json(&params)
        .send()
        .await?;

    // let body = res.bytes().await?;
    let file = File::create("C:\\Users\\sjt\\Desktop\\1.xlsx")?;
    let mut writer = BufWriter::new(file);
    // 流式写入
    while let Some(chunk) = res.chunk().await? {
        writer.write_all(&chunk)?;
    }
    writer.flush()?;
    println!("文件下载完成");

    Ok(())
}

